package edu.zjut.hjg.saas.biz.util;

import java.util.Calendar;
import java.util.Date;

import edu.zjut.hjg.saas.biz.model.PriceType;
import edu.zjut.hjg.saas.biz.support.ChargeType;

public class PriceTypeUtil {
    public static final int FREE_TRIAL_DATES = 15;

    public static Date getEndDate(PriceType priceType, int leaseTerm, boolean withFreeTrial) {
        ChargeType chargeType = priceType.getChargeType();
        Calendar ca = Calendar.getInstance();
        switch (chargeType) {
            case BY_MONTH:
                ca.add(Calendar.MONTH, leaseTerm);
                break;
            case BY_YEAR:
                ca.add(Calendar.YEAR, leaseTerm);
                break;
            default:
                throw new RuntimeException("Unknown priceType: priceType=" + priceType);
        }
        if (withFreeTrial) {
            ca.add(Calendar.DATE, FREE_TRIAL_DATES);
        }
        return ca.getTime();
    }

    /**
     * 是否试用期过期
     * 
     * @param startDate
     * @return
     */
    public static boolean isFreeTrailEnded(Date startDate) {
        Calendar curr = Calendar.getInstance();
        Calendar end = Calendar.getInstance();
        end.setTime(startDate);
        end.add(Calendar.DATE, FREE_TRIAL_DATES);
        boolean sameYear = curr.get(Calendar.YEAR) == end.get(Calendar.YEAR);
        boolean sameDay = curr.get(Calendar.DAY_OF_YEAR) == end.get(Calendar.DAY_OF_YEAR);
        return curr.after(end) || (sameYear && sameDay);
    }

    /**
     * 是否租期已过期
     * 
     * @param endDate
     * @return
     */
    public static boolean isChargingEnded(Date endDate) {
        Calendar curr = Calendar.getInstance();
        Calendar end = Calendar.getInstance();
        end.setTime(endDate);
        boolean sameYear = curr.get(Calendar.YEAR) == end.get(Calendar.YEAR);
        boolean sameDay = curr.get(Calendar.DAY_OF_YEAR) == end.get(Calendar.DAY_OF_YEAR);
        return curr.after(end) || (sameYear && sameDay);
    }

    /**
     * 今天是否计费日
     * 
     * @param startDate
     * @param chargeType
     * @return
     */
    public static boolean isChargingDay(Date startDate, ChargeType chargeType) {
        Calendar curr = Calendar.getInstance();
        Calendar start = Calendar.getInstance();
        start.setTime(startDate);
        int unit;
        int field;
        switch (chargeType) {
            case BY_MONTH:
                unit = Calendar.MONTH;
                field = Calendar.DAY_OF_MONTH;
                break;
            case BY_YEAR:
                unit = Calendar.YEAR;
                field = Calendar.DAY_OF_YEAR;
                break;
            default:
                return false;
        }
        while (curr.after(start)) {
            start.add(unit, 1);
        }
        return curr.get(field) == start.get(field);
    }

    public static double computeLastSpend(Date startDate, PriceType priceType) {
        return getSpend(getLastDays(startDate, priceType), priceType);
    }

    public static int getLastDays(Date startDate, PriceType priceType) {
        Calendar curr = Calendar.getInstance();
        Calendar start = Calendar.getInstance();
        ChargeType chargeType = priceType.getChargeType();
        start.setTime(startDate);
        int unit;
        switch (chargeType) {
            case BY_MONTH:
                unit = Calendar.MONTH;
                break;
            case BY_YEAR:
                unit = Calendar.YEAR;
                break;
            default:
                return 0;
        }
        while (curr.after(start)) {
            start.add(unit, 1);
        }
        start.add(unit, -1);
        // 相差天数
        return (int) ((curr.getTimeInMillis() - start.getTimeInMillis()) / (24 * 60 * 60 * 1000));
    }

    public static double getSpend(int days, PriceType priceType) {
        if (days <= 1) {
            return 0.0;
        }
        double price = priceType.getPrice();
        switch (priceType.getChargeType()) {
            case BY_MONTH:
                if (days < 15) {
                    return price / 2;
                } else {
                    return price;
                }
            case BY_YEAR:
                if (days < 183) {
                    return price / 2;
                } else {
                    return price;
                }
            default:
                return 0.0;
        }
    }
}
